home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
strategy
/
vga_card.000
/
vga_cardgames-1.3.1.tar
/
vga_cardgames
/
vga16.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-26
|
5KB
|
282 lines
/*
* VGA 16 colour mode support routines
*
* Copyright (C) Evan Harris, 1993, 1994, 1995.
*
* Permission is granted to freely redistribute and modify this code,
* providing the author(s) get credit for having written it.
*/
#include <stdlib.h>
#include <stdio.h>
#include <vga.h>
#include "vga16.h"
#define FONT_WIDTH 8
#define FONT_LINES 16
#ifndef USEGETPIXEL
static unsigned char *vga16mem = NULL;
static int vga16width, vga16height;
#endif
static unsigned char *vga16workmem = NULL;
static char *font_bits;
/*
* To be called after vga_setmode()
*/
int
vga16_init()
{
vga_modeinfo *mode;
FILE *f;
int nelem;
mode = vga_getmodeinfo(vga_getcurrentmode());
if (mode->colors != 16) {
return -1;
}
#ifndef USEGETPIXEL
if (vga16mem != NULL) {
free(vga16mem);
}
vga16mem = calloc(mode->width * mode->height / 2, sizeof(unsigned char));
#endif
vga16workmem = malloc(mode->width * sizeof(unsigned char));
nelem = ((FONT_WIDTH + 7) / 8) * FONT_LINES * 256;
font_bits = malloc(nelem * sizeof(char));
#ifndef USEGETPIXEL
if (vga16mem == NULL || vga16workmem == NULL || font_bits == NULL) {
return -1;
}
vga16width = mode->width;
vga16height = mode->height;
#else
if (vga16workmem == NULL || font_bits == NULL) {
return -1;
}
#endif
f = fopen(VGA16FONT, "r");
if (f == NULL) {
fprintf(stderr, "Cannot find '%s'\n", VGA16FONT);
exit(1);
}
if (fread(font_bits, sizeof(char), nelem, f) != nelem) {
fprintf(stderr, "Font reading failed - read error.\n");
}
fclose(f);
return 0;
}
#ifndef USEGETPIXEL
void
vga16_drawscansegment(unsigned char *colors, int x, int y, int length)
{
unsigned char *p, *c;
int l, changed;
p = &vga16mem[(y * vga16width + x) >> 1];
c = colors;
l = length;
changed = 0;
while (l > 0) {
if (*p != (*c << 4 | *(c + 1))) {
*p = *c << 4 | *(c + 1);
changed = 1;
}
p++;
c += 2;
l -= 2;
}
if (changed) {
vga_drawscansegment(colors, x, y, length);
}
}
void
vga16_drawscanline(int y, unsigned char *colors)
{
vga16_drawscansegment(colors, 0, y, vga16width);
}
#endif
static void
vga16_putchar(int x, int y, char c, int fg, int bg)
{
int i, j, mask, colour;
#ifndef USEGETPIXEL
int vp;
#endif
y -= FONT_LINES - 1;
for (i = FONT_LINES * c; i < FONT_LINES * (c + 1); i++) {
mask = 0x80;
for (j = x; j < x + 8; j++) {
if (font_bits[i] & mask) {
colour = fg;
} else {
colour = bg;
}
#ifndef USEGETPIXEL
vp = (y * vga16width + j) / 2;
if (j & 1) {
if ((vga16mem[vp] & 0x0f) != colour) {
vga16mem[vp] = (vga16mem[vp] & 0xf0) | colour;
vga_setcolor(colour);
vga_drawpixel(j, y);
}
} else {
if ((vga16mem[vp] >> 4) != colour) {
vga16mem[vp] = (colour << 4) | (vga16mem[vp] & 0x0f);
vga_setcolor(colour);
vga_drawpixel(j, y);
}
}
#else
vga_setcolor(colour);
vga_drawpixel(j, y);
#endif
mask = mask >> 1;
}
y++;
}
}
void
vga16_text(int x, int y, char *s, int fg, int bg)
{
int startx = x;
while (*s != '\0') {
switch (*s) {
case '\n':
y += FONT_LINES;
x = startx;
break;
case '\b':
x -= FONT_WIDTH;
break;
default:
vga16_putchar(x, y, *s, fg, bg);
x += FONT_WIDTH;
break;
}
s++;
}
}
void
vga16_setpixel(int color, int x, int y)
{
#ifndef USEGETPIXEL
unsigned char *vp = &vga16mem[(y * vga16width + x) >> 1];
if (x & 1) {
if ((*vp & 0x0f) == color) {
return;
}
*vp = (*vp & 0xf0) | color;
} else {
if ((*vp >> 4) == color) {
return;
}
*vp = (color << 4) | (*vp & 0x0f);
}
#endif
vga_setcolor(color);
vga_drawpixel(x, y);
}
#ifndef USEGETPIXEL
int
vga16_getpixel(int x, int y)
{
unsigned char *vp = &vga16mem[(y * vga16width + x) >> 1];
if (x & 1) {
return *vp & 0x0f;
} else {
return *vp >> 4;
}
}
#endif
/*
* This assumes that (x0 % 8 == 0) and (x1 % 8 == 7) due to
* vga_drawscansegment()
*/
void
vga16_filledblock(int x0, int y0, int x1, int y1, int color)
{
int x, y;
#ifndef USEGETPIXEL
unsigned char *vp;
int c;
#endif
for (x = 0; x <= x1 - x0; x++) {
vga16workmem[x] = color;
}
for (y = y0; y <= y1; y++) {
#ifndef USEGETPIXEL
x = x0;
c = (color << 4) | color;
vp = &vga16mem[(y * vga16width + x) >> 1];
if (x & 1) {
*vp++ = (*vp & 0xf0) | color;
x++;
}
while (x <= x1 - 1) {
*vp++ = c;
x += 2;
}
if (x < x1) {
*vp++ = (*vp & 0x0f) | (color << 4);
}
#endif
vga_drawscansegment(vga16workmem, x0, y, x1 - x0 + 1);
}
}
void
vga16_redrawscreen()
{
#ifndef USEGETPIXEL
unsigned char *vp, *vw;
int x, y;
for (y = 0; y < vga16height; y++) {
vp = &vga16mem[(y * vga16width) >> 1];
vw = vga16workmem;
for (x = 0; x < vga16width / 2; x++) {
*vw++ = (*vp & 0xf0) >> 4;
*vw++ = *vp++ & 0x0f;
}
vga_drawscansegment(vga16workmem, 0, y, vga16width);
}
#endif
}